package com.bestv.search.management.command;

import com.bestv.search.common.cache.SystemCache;
import com.bestv.search.common.dataSource.DataSourceKey;
import com.bestv.search.common.dataSource.DataSourceKeyUtil;
import com.bestv.search.common.model.SearchKeyword;
import com.bestv.search.common.model.SysUser;
import com.bestv.search.common.model.TopKeyword;
import com.bestv.search.common.service.SearchKeywordHistoryManager;
import com.bestv.search.common.service.SearchKeywordManager;
import com.bestv.search.common.service.TopKeywordManager;
import com.bestv.search.common.service.TopNCacheManager;
import com.bestv.search.common.util.CharUtil;
import com.bestv.search.common.util.ChineseCharToEn;
import com.bestv.search.common.util.StringConst;
import com.bestv.search.management.xfire.ISearchWS;
import org.apache.log4j.Logger;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Michael Wang
 */

// $Id: TopKeywordCommand.java 109 2012-08-16 06:30:44Z wbwang $
public class TopKeywordCommand {

    private final static int COUNT_DECIDE_ONE_CAN_BE_TOP = 10;
    Logger logger = Logger.getLogger(TopKeywordCommand.class);
    private SearchKeywordManager searchKeywordManager;
    private TopKeywordManager topKeywordManager;
    private SearchKeywordHistoryManager searchKeywordHistoryManager;
    private TopNCacheManager topNCacheManager;
    private SystemCache systemCache;

    public void calcAndStoreTopKeyword(String siteCode) {
        DataSourceKey key = DataSourceKeyUtil.convert(siteCode);
        Map<String, Integer> topKeywordMap = searchKeywordManager.sumEachKeyword(key);
        List<TopKeyword> storeList = new ArrayList<TopKeyword>();
        for (String keyword : topKeywordMap.keySet()) {
            if (shouldBeFiltered(keyword))
                continue;
            if (topKeywordMap.get(keyword) < COUNT_DECIDE_ONE_CAN_BE_TOP)
                continue;

            TopKeyword top = null;
            List<TopKeyword> topKeywords = topKeywordManager.getTopKeywordByKeyword(key, keyword);
            if (topKeywords != null && topKeywords.size() != 0) {
                top = topKeywords.get(0);
            }

            // 每天执行一次
            if (top != null) {
                top.setCount(top.getCount() + topKeywordMap.get(keyword));
            } else {
                top = new TopKeyword();
                top.setKeyword(keyword);
                String py = ChineseCharToEn.getAllFirstLetter(keyword);
                top.setPy(py);
                top.setNum(CharUtil.charToNum(py));
                top.setCount(topKeywordMap.get(keyword));
            }
            storeList.add(top);
        }
        topKeywordManager.saveTopKeywords(key, storeList);
    }

    private boolean shouldBeFiltered(String keyword) {
        return keyword.length() < 2 || keyword.contains(" ");
    }

    public SearchKeywordManager getSearchKeywordManager() {
        return searchKeywordManager;
    }

    public void setSearchKeywordManager(SearchKeywordManager searchKeywordManager) {
        this.searchKeywordManager = searchKeywordManager;
    }

    public TopKeywordManager getTopKeywordManager() {
        return topKeywordManager;
    }

    public void setTopKeywordManager(TopKeywordManager topKeywordManager) {
        this.topKeywordManager = topKeywordManager;
    }

    public void clearSearchKeywords(String siteCode) {
        DataSourceKey key = DataSourceKeyUtil.convert(siteCode);
        searchKeywordManager.clearKeywords(key);
    }

    public List<SearchKeyword> getTimeSortedKeywords(String siteCode) {
        DataSourceKey key = DataSourceKeyUtil.convert(siteCode);
        return searchKeywordManager.getTimeSortedKeywords(key);
    }

    public String getTopKeyword(SysUser user, Map<String, String[]> map, DataSourceKey dsKey) {
        String[] keywords = map.get("keyword");
        String[] starts = map.get("start");
        String[] limits = map.get("limit");

        int startInt = 0;
        if (starts != null && starts.length > 0) {
            try {
                startInt = Integer.valueOf(starts[0]);
            } catch (Exception e) {
                logger.warn("Invalid parameter start " + starts[0]);
                startInt = 0;
            }
        }

        int limitInt = 20;
        if (limits != null && limits.length > 0) {
            try {
                limitInt = Integer.valueOf(limits[0]);
            } catch (Exception e) {
                logger.warn("Invalid parameter limit " + limits[0]);
                limitInt = 20;
            }
        }

        // Gets topKeywords
        List<TopKeyword> list = null;
        int total = 0;
        if (keywords == null || keywords.length == 0 || keywords[0].trim().equals(StringConst.EMPTY)) {
            list = topKeywordManager.getTopKeywords(dsKey, startInt, limitInt);
            total = topKeywordManager.getTotalCount(dsKey);
        } else {
            list = topKeywordManager.getTopKeywordByKeyword(dsKey, keywords[0], startInt, limitInt);
            total = topKeywordManager.getTotalCountByKeyword(dsKey, keywords[0]);
        }

        // Build Json results
        JSONArray array = new JSONArray();
        for (TopKeyword topKeyword : list) {
            JSONObject json = new JSONObject();
            try {
                json.put("keyword", topKeyword.getKeyword());
                json.put("spell", topKeyword.getPy());
                json.put("number", topKeyword.getNum());
                json.put("count", topKeyword.getCount());
                array.put(json);
            } catch (JSONException e) {
                logger.error("Convert to Json object failed.");
                e.printStackTrace();
            }
        }

        return "{'totalCount':" + total + ",'results':" + array.toString() + "}";
    }

    public String deleteTopKeyword(SysUser user, Map<String, String[]> map, DataSourceKey dsKey) {
        String[] keywords = map.get("keyword");

        if (keywords == null || keywords.length == 0 || keywords[0].trim().equals(StringConst.EMPTY)) {
            logger.error("Invalid parameter keyword");
            return "error";
        } else {
            String keyword = null;
            try {
                keyword = new String(keywords[0].getBytes(StringConst.ISO_8859_1), StringConst.UTF_8);
                logger.debug("the delete keyoword:"+keyword);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            // delete from table top_keyword.
            topKeywordManager.removeTopKeyword(dsKey, keyword);

            // delete from table searchKeyword_History
            searchKeywordHistoryManager.deleteHistroyByKeyword(dsKey, keyword);

            // delete from table topNCache
            int deleteCount = topNCacheManager.deleteHistroyByKeyword(dsKey, keyword);
            if (deleteCount > 0) {
                // update topNCache to memory cache
                updateEngineTopMemoryCache(dsKey.toString());
            }
        }

        return "success";
    }

    private void updateEngineTopMemoryCache(String siteCode) {
        ISearchWS service;
        Service serviceModel = new ObjectServiceFactory().create(ISearchWS.class);
        String url = systemCache.getWebServiceEngineUrls().get(siteCode);
        String[] soapUrls = StringUtils.tokenizeToStringArray(url, SystemCache.WEB_SERVICE_EURL_DELIMITERS);
        if (soapUrls == null || soapUrls.length == 0) {
            logger.error("UpdateEngineTopMemoryCache failed, no web service interface found from site " + siteCode);
            return;
        }

        try {
            for (int i = 0; i < soapUrls.length; i++) {
                String soapUrl = soapUrls[i];
                logger.debug("UpdateEngineTopMemoryCache from " + soapUrl);

                service = (ISearchWS) new XFireProxyFactory().create(serviceModel, soapUrl);
                service.updateTopNCacheInMemory();

                logger.debug("UpdateEngineTopMemoryCache end from " + soapUrl);
            }
        } catch (Exception e) {
            logger.error("updateEngineTopMemoryCache failed due to ");
            e.printStackTrace();
        }
    }

    public SearchKeywordHistoryManager getSearchKeywordHistoryManager() {
        return searchKeywordHistoryManager;
    }

    public void setSearchKeywordHistoryManager(SearchKeywordHistoryManager searchKeywordHistoryManager) {
        this.searchKeywordHistoryManager = searchKeywordHistoryManager;
    }

    public TopNCacheManager getTopNCacheManager() {
        return topNCacheManager;
    }

    public void setTopNCacheManager(TopNCacheManager topNCacheManager) {
        this.topNCacheManager = topNCacheManager;
    }

    public SystemCache getSystemCache() {
        return systemCache;
    }

    public void setSystemCache(SystemCache systemCache) {
        this.systemCache = systemCache;
    }
}
